#include "SdkMotionDetectArea.h"

#define DEF_TAG             "MDArea"

SAreaPoints g_SdkMotionDetectArea_Points;

Com_void Ext_SdkMotionDetectArea_ParsePointsZone(Com_ps8 zone)
{
    int i = 0,iCnt = 0;

    OSC_cJSON * points_array = OSC_cJSON_Parse(zone);
    if (NULL == points_array)
    {
        PRT_ERR(DEF_TAG,"step error\n");
        OSC_cJSON_Delete(points_array);
        return;
    }

    do{
        int array_size = OSC_cJSON_GetArraySize(points_array);
        if(array_size == 0)
        {
            break;
        }

        OSC_cJSON * pSub_array = NULL;
        OSC_cJSON * pSub = NULL;
        OSC_cJSON * pX = NULL;
        OSC_cJSON * pY = NULL;

        PRT_INFO(DEF_TAG,"array size: %d\n",array_size);
        if(array_size > 0)
        {
            pSub_array = OSC_cJSON_GetArrayItem(points_array, 0);
            iCnt = OSC_cJSON_GetArraySize(pSub_array);
            if(iCnt != 6)
            {
                break;
            }

            for(i = 0 ; i < iCnt ; i ++ )
            {
                pSub = OSC_cJSON_GetArrayItem(pSub_array, i);
                if(NULL == pSub )
                {
                    continue;
                }

                pX = OSC_cJSON_GetArrayItem(pSub, 0);
                pY = OSC_cJSON_GetArrayItem(pSub, 1);
                g_SdkMotionDetectArea_Points.points0[i].x =pX->valueint;
                g_SdkMotionDetectArea_Points.points0[i].y =pY->valueint;

                PRT_INFO(DEF_TAG,"Point1[%d] x:%d y:%d\n",
                            i,g_SdkMotionDetectArea_Points.points0[i].x,g_SdkMotionDetectArea_Points.points0[i].y);
            }
            g_SdkMotionDetectArea_Points.point_num = 1;
        }

        if(array_size > 1)
        {
            pSub_array = OSC_cJSON_GetArrayItem(points_array, 1);
            iCnt = OSC_cJSON_GetArraySize(pSub_array);
            if(iCnt != 6)
            {
                break;
            }
            for(i = 0;i < iCnt;i++)
            {
                pSub = OSC_cJSON_GetArrayItem(pSub_array, i);
                if(NULL == pSub)
                {
                    continue;
                }
                pX = OSC_cJSON_GetArrayItem(pSub, 0);
                pY = OSC_cJSON_GetArrayItem(pSub, 1);
                g_SdkMotionDetectArea_Points.points1[i].x =pX->valueint;
                g_SdkMotionDetectArea_Points.points1[i].y =pY->valueint;

                PRT_INFO(DEF_TAG,"Point2[%d] x:%d y:%d\n",
                            i,g_SdkMotionDetectArea_Points.points1[i].x,g_SdkMotionDetectArea_Points.points1[i].y);
            }
            g_SdkMotionDetectArea_Points.point_num=2;
        }
    }while(0);

    OSC_cJSON_Delete(points_array);
}

char SdkMotionDetectArea_IsInSide(SPointLatLng *p,SPointLatLng area[])
{
    int px = p->x;
    int py = p->y;
    int sx = 0;
    int sy = 0;
    int tx = 0;
    int ty = 0;
    int i = 0;
    int j = 0;
    char flag = 0;

    for(i = 0,j = 6 - 1; i < 6; j = i, i++)
    {
        sx = area[i].x;
        sy = area[i].y;
        tx = area[j].x;
        ty = area[j].y;

        // 点与多边形顶点重合
        if((sx == px && sy == py) || (tx == px && ty == py))
        {
            return 1;
        }

        // 判断线段两端点是否在射线两侧
        if((sy < py && ty >= py) || (sy >= py && ty < py))
        {
            // 线段上与射线 Y 坐标相同的点的 X 坐标
            int x = sx + (py - sy) * (tx - sx) / (ty - sy);
            // 点在多边形的边上
            if(x == px)
            {
                return 1;
            }

            // 射线穿过多边形的边界
            if(x > px)
            {
                flag = !flag;
            }
        }
    }

    return flag;
}

Com_s32 SdkMotionDetectArea_Handle(Com_s32 area_v,Com_s32 area_h)
{
    if(g_SdkMotionDetectArea_Points.point_num > 0)
    {
        char flg = 0,flg2 = 0;
        SPointLatLng p;

        p.x = (1920 / DEF_MD_AREA_V_NUM) * area_v;
        p.y = (1080 / DEF_MD_AREA_H_NUM) * area_h;
        flg2 = 0;

        switch(g_SdkMotionDetectArea_Points.point_num)
        {
        case 0:
            flg++;
            break;

        case 2:
            flg2 = SdkMotionDetectArea_IsInSide(&p,g_SdkMotionDetectArea_Points.points1);
            if(flg2==1)
            {
                flg++;
            }

        case 1:
            if(flg2 == 0)
            {
                flg2 = SdkMotionDetectArea_IsInSide(&p,g_SdkMotionDetectArea_Points.points0);
                if(flg2==1)
                {
                    flg++;
                }
            }
            break;
        }

        if(flg > 0)
        {
            PRT_INFO(DEF_TAG,"----->md area trigger\n");
            return DEF_COM_TRUE;
        }

        return DEF_COM_FALSE;
    }
    else
    {
        return DEF_COM_TRUE;
    }
}

Com_s32 Ext_SdkMotionDetectArea_GetResult(Com_void)
{
    if(g_SdkMotionDetectArea_Points.point_num == 0)
    {
        return DEF_COM_SUCCESS;
    }

    StSdkMDAreaLocal local;

    memset(&local,0,sizeof(local));
    Ext_SdkMediaCom_GetMDAreaXY(&local);

    if(SdkMotionDetectArea_Handle(local.l,local.t) || SdkMotionDetectArea_Handle(local.l,local.b) ||
       SdkMotionDetectArea_Handle(local.r,local.t) || SdkMotionDetectArea_Handle(local.r,local.b))
    {
        return DEF_COM_SUCCESS;
    }
    else
    {
        return DEF_COM_FAILED;
    }
}

Com_void Ext_SdkMotionDetectArea_Init(Com_void)
{
    memset(&g_SdkMotionDetectArea_Points,0,sizeof(g_SdkMotionDetectArea_Points));

    g_SdkMotionDetectArea_Points.point_num = 0;
}
